#pragma once

#include <qbcalculator/include/SSSingleInterestRate.h>

#include <list>
#include <map>
#include <mutex>
#include <vector>

#include "../core.h"

using namespace std;

typedef struct ST_Macro_Index {
  char code[32];
  double fvalue;
  int begin_date;
  int end_date;
} Macro_Index;
struct Macro_Index_Value {
  double fvalue;
  int begin_date;
  int end_date;
};

class Macro_Comp {
 public:
  bool operator()(const Macro_Index_Value &lhs, const Macro_Index_Value &rhs) {
    return lhs.begin_date < rhs.begin_date;
  }

  bool operator()(const int &lhs, const Macro_Index_Value &rhs) {
    return lhs < rhs.begin_date;
  }

  bool operator()(const Macro_Index_Value &lhs, const int &rhs) {
    return lhs.begin_date < rhs;
  }
};

class S_CORE_EXPORT CBondMacroData {
 public:
  // std::vector<Macro_Index> m_data;
  typedef std::vector<Macro_Index_Value> MacroValueList;
  typedef std::map<string, MacroValueList> CodeMacroListMap;
  CodeMacroListMap m_values;
};

class S_CORE_EXPORT CMacroList {
 public:
  std::list<Macro_Index> m_list;
};

class S_CORE_EXPORT CBondMacroIndex {
  typedef CBondMacroData::CodeMacroListMap CodeMacroListMap;
  typedef CBondMacroData::MacroValueList MacroValueList;

 public:
  class ILoader {
   public:
    virtual void LoadMacroIndex(CBondMacroIndex *pTarget) {}
  };

 public:
  static CBondMacroIndex &instance();
  bool Clear();
  void Add(const char *code, const Macro_Index_Value &element);
  bool Load(ILoader *loader);
  int GetSize();
  double GetMaxDateByCod(const char *pCode);
  CBondMacroData &GetBondMacro();
  void SortMacroIndex();
  int GetAllData(std::vector<ssCalculator::SSSingleInterestRate> &rates,
                 int capcity);

 private:
  CBondMacroIndex();
  virtual ~CBondMacroIndex();

 protected:
  CBondMacroData m_macro_data;
  std::mutex m_mutex;
};
